#include "ChatServer.h"
#include "../utils/Logger.h"
#include "../utils/UtilString.h"
#include "../communication/SocketProtocoloPlano.h"
#include "../communication/FifoProtocoloPlano.h"
#include "../communication/Mensajes/MensajeAgregarUsuario.h"
#include "../communication/Mensajes/MensajeTexto.h"
#include "../communication/Mensajes/MensajeRemoverUsuario.h"
#include "../Signals/SIGINT_Handler.h"
#include "../Signals/SignalHandler.h"
#include "../utils/Config.h"
#include "Chat_Admin.h"
#include <errno.h>
#include <iostream>
#include <getopt.h>
#include <stdio.h>
#include <sys/wait.h>
#include <fstream>
#include "../utils/Tp2Utils.h"


ChatServer::ChatServer() : queue(MAIN_QUEUE, 'a'){
}

ChatServer::~ChatServer() {
	this->queue.cerrar();
}

void ChatServer::showHelp() {
	std::cout << "Comandos posibles:"
			<< " [--help|-h] "
			<< " [--servidor-ip|-s=ip] "
			<< " [--servidor-puerto|-p=puerto]" << std::endl;

	std::cout << "\t--help -h\t\tMuestra esta ayuda" << std::endl;
	std::cout
			<< "\t--servidor-puerto -p\t\tPuerto del Servidor a crear"
			<< std::endl;
}

ChatServer::Configuracion ChatServer::parseParams(int argc, char **argv) {
	Configuracion configuracion;
	struct option long_options[] = {
			{ "help", no_argument, 0, 'h' },
			{ 0, 0,0, 0 }
	};
	int option_index = 0;
	int c = -1;

	while ((c = getopt_long(argc, argv, "h", long_options,&option_index)) != -1) {
		switch (c) {
		case 'h':
			showHelp();
			exit(0);

			break;
		default:
			showHelp();
			exit(1);
			break;
		}
	}
	return configuracion;
}

int ChatServer::runProcess(int argc, char **argv){

	Logger::init();
	Logger::getInstance().setProcessInformation("Server_ppal");
	// event handler para la senial SIGINT (-2)
	SIGINT_Handler sigint_handler;
	// se registra el event handler declarado antes
	SignalHandler::getInstance()->registerHandler(SIGINT, &sigint_handler);

	while (sigint_handler.getGracefulQuit() == 0 )
	{
		lecturaDeMensajes();
	}

	Logger::getInstance().logMessage(Logger::TRACE, "Sali del loop");


	return 0;
}


void ChatServer::lecturaDeMensajes(){

	//leer mensaje desde cola de admin
	Mensaje* msg = NULL;
	while( (msg = queue.leerMensaje(SERVER_ID) ) != NULL )
	{
		Logger::getInstance().logMessage(Logger::TRACE, "lecturaDeMensajes :: lei un mensaje de un cliente");

		MensajeConAutorYPid* message = static_cast<MensajeConAutorYPid*> (msg);
		switch (message->getType()) {
			case AGREGAR_USUARIO:{

				//Si llego mensaje de agregar usuario y son manager del chat, agrego el fifo
				MensajeAgregarUsuario* messageAddUser = static_cast<MensajeAgregarUsuario*> (message);
				Logger::getInstance().logMessage(Logger::TRACE, "Proceso - MENSAJE AGREGAR USUARIO, de queue, en chat:" + messageAddUser->getNombreChat());

				//Agrego el usuario a lista de usuarios
				chatAdmin.registrarNuevoCliente(messageAddUser);

			}break;
			case REMOVER_USUARIO:{
				Logger::getInstance().logMessage(Logger::TRACE, "Leo un mensaje de desconexion de usuario");

				MensajeRemoverUsuario* messageRemover = static_cast<MensajeRemoverUsuario*> (msg);

				chatAdmin.unregistrarCliente(messageRemover);

			}break;
			case MENSAJE_TEXTO:
				chatAdmin.enviarMensaje(message);
				break;
			case MENSAJE_QUERY_CHATS:
				chatAdmin.obtenerListadoChats(message->getPid());
			default:
				Logger::getInstance().logMessage(Logger::ERROR, "Recibi un mensaje incorrecto para esta etapa");
				break;
		}

		//Borro el mensaje
		delete msg;
	}

}
